import mxgraph from 'pages/mxgraph/graph/index';
import { UMLDIHelper } from 'src/api/sysml-imports';
import graphUtil from "pages/mxgraph/graphUtil";
import { ConnectionHandler } from './ConnectionHandler';
import {  MofModelHelper } from 'src/api/sysml-imports';
import { PropertyUtil } from 'src/components/Attribute/comps/PropertyUtil';
import './GraphHandler';
import './Rubberband';
import './VertexHandler';
import './EdgeHandler';
import './CellEditor';
import './GraphView';
import './GraphModel';
import '../shapes/customShapes';

const {
  mxGraph,

  mxEventObject,
  mxEvent,
  mxConstants

} = mxgraph;

//// 变灰重置
mxGraph.prototype.resetMask = function () {
  console.log('变灰重置');
  const mGraph = this;
  mGraph.inConnecting = 0;
  mGraph.model.beginUpdate();
  let allcells = [];
  let cells = mGraph.model.cells;
  //// 获得graph中除0，1节点外的所有节点
  Object.keys(cells).forEach(function (key) {
    if (!isNaN(Number(key))) {
      allcells.push(cells[key]);
    }
  });
  mGraph.setCellStyles('opacity', '100', allcells);
  //// mGraph.setCellStyles('fontColor', '#000000', allcells);
  mGraph.setCellStyles('isLocked', '0', allcells);
  mGraph.clearSelection();
  mGraph.model.endUpdate();
};

const init = mxGraph.prototype.init; 
mxGraph.prototype.init = function () {
  console.log('init-----');
  init.apply(this, arguments);
};

//// todo 存在外部依赖 mEditorUi
//// mxGraph.prototype.setMask = function (typeName) {
////   //// 当拖进画布时，进行图形类型判断，是否置灰
////   const mGraph = this;
////   mGraph.model.beginUpdate();
////   console.log('变灰');
////   //// 获得graph中除0，1节点外的所有节点
////   let gcells = mGraph.model.cells;
////   let changedCells = [];
////   let noChanged = [];
////   //// 判断type是图形还是关系
////   if (!edgeApi.isEdgeShape({ typeName })) {
////     //// type是图形
////     Object.keys(gcells).forEach(key => {
////       if (!isNaN(Number(key)) && 'typeName' in gcells[key]) {
////         //// && !mEditorUi.sidebar.isEdgeShape(gcells[key].typeName) 可能要加上线条不变灰
////         if (!graphUtil.isCreateInShape({ typeName, modelName: gcells[key].typeName }) && !edgeApi.isEdgeShape({ typeName: gcells[key].typeName })) {
////           changedCells.push(gcells[key]);
////         } else {
////           noChanged.push(gcells[key]);
////         }
////       }
////     });
////   } else {
////     //// type是关系
////     Object.keys(gcells).forEach(key => {
////       if (!isNaN(Number(key)) && 'typeName' in gcells[key]) {
////         //// && !mEditorUi.sidebar.isEdgeShape(gcells[key].typeName) 可能要加上线条不变灰
////         if (!graphUtil.isConnectWithShape({ lineName: typeName, modelName: gcells[key].typeName }) && !edgeApi.isEdgeShape({ typeName: gcells[key].typeName })) {
////           changedCells.push(gcells[key]);
////         } else {
////           noChanged.push(gcells[key]);
////         }
////       }
////     });
////   }

////   if (changedCells.length != 0) {
////     mGraph.setCellStyles('opacity', '20', changedCells);
////     //// mGraph.setCellStyles('fontColor', '#C9C9C9', changedCells);
////     mGraph.setCellStyles('isLocked', '1', changedCells);
////     //// 去掉下一行也可以
////     this.fireEvent(new mxEventObject('styleChanged', 'keys', ['opacity', 'fontColor', 'isLocked'], 'values', ['20', '#C9C9C9', '1'], 'cells', changedCells));
////   }
////   if (noChanged.length != 0) {
////     mGraph.setCellStyles('opacity', '100', noChanged);
////     mGraph.setCellStyles('fontColor', '#000000', noChanged);
////     mGraph.setCellStyles('isLocked', '0', noChanged);
////     this.fireEvent(new mxEventObject('styleChanged', 'keys', ['opacity', 'fontColor', 'isLocked'], 'values', ['100', '#000000', '0'], 'cells', noChanged));
////   }
////   mGraph.model.endUpdate();
//// };

mxGraph.prototype.isCellLocked = function (cell) {
  if (cell && cell.style) {
    return cell.style.indexOf('isLocked=1') > -1;
  }
  return false;
};
mxGraph.prototype.createCurrentEdgeStyle = function () {

  let curEdgeType = app.ui.curEdgeType; ////
  let style = UMLDIHelper.getRelationStyleByTypeName(curEdgeType);
  if (!style.endsWith(';')){
    style += ';';
  }
  return style;
};

//// 阻止默认的keyPress的编辑名字，防止编辑edge的默认value
const mxgraphStartEditingAtCell =  mxGraph.prototype.startEditingAtCell;
mxGraph.prototype.startEditingAtCell = function (cell, evt) {
  console.log('startEditingAtCell');
  if (!cell || cell.edge || cell.umlShape.container.disabled == true) return;
  return mxgraphStartEditingAtCell.apply(this, arguments);

};

//// 在图中拖拽元素时判断是否可以drop
//// const isValidDropTarget = mxGraph.prototype.isValidDropTarget; 
//// mxGraph.prototype.isValidDropTarget = function (target){
////   const movingCells = this.graphHandler.cells;

////   if (!graphUtil.isValidDropTarget(this, movingCells, target)) return false;

////   return isValidDropTarget.apply(this, arguments);
//// };

/**
 * 移动连接点时更新关系以及style
 * @param {*} edge 
 * @param {*} terminal 
 * @param {*} source 
 * @param {*} constraint 
 */
mxGraph.prototype.connectCell = function(edge, terminal, source, constraint){
  console.log('connectCell---', terminal);
  this.model.beginUpdate();
  try
  { 
    if (source) {
      if (edge.source.umlShape.id !== terminal.umlShape.id) {
        edge.umlShape.container.updateSource(terminal.umlShape.container);
        edge.umlShape.updateSource(terminal.umlShape);
      }

    } else {
      if (edge.target.umlShape.id !== terminal.umlShape.id) {
        edge.umlShape.container.updateTarget(terminal.umlShape.container);
        edge.umlShape.updateTarget(terminal.umlShape);
      }

    }
    
    let previous = this.model.getTerminal(edge, source);
    this.cellConnected(edge, terminal, source, constraint);
    edge.umlShape.box.style = edge.style;
    //// edge.umlShape && edgeApi.updateEdgeStyle(edge.umlShape,  edge.style);
    this.fireEvent(new mxEventObject(mxEvent.CONNECT_CELL,
      'edge', edge, 'terminal', terminal, 'source', source,
      'previous', previous));
  }
  finally
  {
    this.model.endUpdate();
  }

  return edge;
};

//// 移动cell时，获取drop的target的，如果没有target则返回diagram的cell， todo 批量拖动 ,
//// 连线的时候，第二次点击选择目标也调用了此方法
mxGraph.prototype.getDropTarget = function(cells, evt, cell, clone)
{
  //// console.log('getDropTarget', cells[0], cell, this.diagram);
  if (!cell)  return this.model.cells[this.diagramShape.id];
  if (!graphUtil.isMainShape(cells[0].umlShape)) return cells[0].parent;
  const mainCell = graphUtil.getMainCell(cell);
  if (cells[0].id === mainCell.id) return mainCell.parent;
  return mainCell;

};

//// 使用继承后的ConnectionHandler
mxGraph.prototype.createConnectionHandler = function(){
  return new ConnectionHandler(this);
};

mxGraph.prototype.getCursorForCell = function(cell)
{
  return this.view.getState(cell).style.cursor || null;
};

const getEditingValue = mxGraph.prototype.getEditingValue;
mxGraph.prototype.getEditingValue = function(cell){
  //// console.log(cell, 'cccc-c-c-c--');
  //// Requirement slot 特殊处理，获取slot的值
  //// cell.umlShape.getEditingValue()
  const shapeTypeName = cell.umlShape.getTypeName();
  if (cell.umlShape && cell.umlShape.container && cell.umlShape.container.getTypeName() === 'Slot'){
    const model =  cell.umlShape.container.container.container.model;
    const property =  cell.umlShape.container.model.getDefiningFeature();
    const val = MofModelHelper.getPropertyValue(model, property);
    
    //// getNodePropertyValue(graphNode:GraphNode, property:string | any)
    //// console.log(reqNode, property, val);
    return val;
  } else if (shapeTypeName === 'Note' || shapeTypeName === 'TextBox') {
    return cell.umlShape.text;

  } else {
    return cell.umlShape.container.title;

  }

};

//// //// 复写那些cell可以被选择
//// mxGraph.prototype.isCellSelectable = function(cell){
////   console.log(cell, cell.deep > 0, 's-------------------');
////   return cell.deep > 0;
////   //// return this.isCellsSelectable();
//// };
mxGraph.prototype.enterStopsCellEditing = true;//// 按下回车时直接保存,如果按住shift+enter则换行

mxGraph.prototype.resetEdgesOnConnect = false;
mxGraph.prototype.extendParentsOnAdd = false; //// 新增cell时是否自动扩展父元素大小,改为不扩展，扩展时会导致打开画布时重复更新size
mxGraph.prototype.extendParents = false; //// 子元素resize时自动扩展父元素，改为false,因为port就是可以在一半在父元素外面
mxGraph.prototype.connectableEdges = true;//// 线要可以连接

mxConstants.DEFAULT_FONTSIZE = 12;
